package com.qst.rongxiaotong.utils;

import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Date;
import java.util.Map;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

public class JwtUtil {

    /**
     * 生成 JWT
     * 使用 HS256 算法，私钥使用固定秘钥。
     *
     * @param secretKey jwt 秘钥
     * @param ttlMillis jwt 过期时间（毫秒）
     * @param claims    设置的信息，包含在 JWT 的负载部分
     * @return 生成的 JWT 字符串
     */
    public static String createJWT(String secretKey, long ttlMillis, Map<String, Object> claims) {
        // 指定签名使用的算法，这里使用 HS256 算法
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;

        // 计算 JWT 的过期时间
        long expMillis = System.currentTimeMillis() + ttlMillis; // 当前时间加上过期时间
        Date exp = new Date(expMillis); // 创建一个 Date 对象表示过期时间

        // 设置 JWT 的主体部分
        JwtBuilder builder = Jwts.builder()
                // 设置自定义的声明（claims）
                .setClaims(claims)
                // 设置签名使用的算法和秘钥
                .signWith(signatureAlgorithm, secretKey.getBytes(StandardCharsets.UTF_8))
                // 设置 JWT 的过期时间
                .setExpiration(exp);

        // 返回生成的 JWT 字符串
        return builder.compact();
    }

    /**
     * Token 解密
     *
     * @param secretKey jwt 秘钥，此秘钥必须保留在服务端，不能暴露给客户端
     *                  否则可能导致签名被伪造。若有多个客户端，建议使用不同的秘钥。
     * @param token     加密后的 JWT
     * @return 解析后的声明（Claims）
     */
    public static Claims parseJWT(String secretKey, String token) {
        // 得到DefaultJwtParser
        Claims claims = Jwts.parser()
                // 设置签名的秘钥
                .setSigningKey(secretKey.getBytes(StandardCharsets.UTF_8))
                // 设置需要解析的jwt
                .parseClaimsJws(token).getBody();
        return claims;
    }

}
